/* Copyright (C) 2011 Fredrique Samuels, fredriquesamuels@gmail.com 

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
#ifndef TRI_SIMULATION_ENTITY_H__
#define TRI_SIMULATION_ENTITY_H__


#include "../base/vector.h"
#include "../base/matrix.h"
#include "../shapes.h"


#include <stdlib.h>
#include <Newton.h>

#include "../base/logging.h"
#include "../scene.h"

#include "physics_common.h"
#include "collision_utils.h"

namespace tri{

enum {
	PHYSICS_BOX,
	PHYSICS_SPHERE,
	PHYSICS_CYLINDER
};


class TSimulationScene;


/**
 * Object containing a physics
 * and graphics component.
 */
class TSimulationEntity{
	
	friend class TSimulationScene;
	
public:
	TSimulationEntity(NewtonWorld* world = NULL, int id=0);
	virtual ~TSimulationEntity();
	
	void setGraphicComponent(tri::TEntity* ent, int modelType, float mass, bool owner=false);
//	void setGraphicComponent(tri::TCube* ent,float mass);
//	void setGraphicComponent(tri::TSphere* ent,float mass);
	
	tri::TEntity* getGraphicsComponent();
	tri::TEntity* getPhysicsModelComponent();
	NewtonBody* getPhysicsBody();
	
	void setMaterialGroup(int group);
	void setTransformation(tri::TVector rot, tri::TVector pos);
	void applyForce(tri::TVector);
	void setForce(tri::TVector);
	tri::TVector getForce();
	tri::TVector getVelocity(); 
	void setVelocity(tri::TVector); 
	float getMass();
	void setIgnoreRotation(bool);
	bool ignoreRotation();
	int getID();
	
	
	void setWorld(NewtonWorld*);
	void initPhysics();
	void clearPhysics();
	void clearGraphics();
	
private:
	bool isOwnedByParent();
	void freeParent();
	void setParent(TSimulationScene* scene, bool owner=false);
	TSimulationScene* getParent();
	
	tri::TEntity* m_GraphicComponent;
	tri::TEntity* m_PhysicsModelComponent;
	NewtonBody* m_PhysicsComponent;
	int m_PhysicsModel;
	float m_Mass;
	NewtonWorld* m_NewtonWorld;
	bool m_IgnoreRotation;
	bool m_OwnerOfGraphics;
	tri::TVector m_TotalForce;
	int mID;
	TSimulationScene* m_Parent;
	bool m_OwnedByParent;
};

//
//class TSimulationWorld : public tri::TScene{
//public:
//	TSimulationWorld();
//	virtual ~TSimulationWorld();
//	
//protected:
//	typedef std::set<TSimulationEntity*> TSimEntitySet;
//	typedef std::set<TSimulationEntity*>::const_iterator ConstIterator;
//
//public:
//	virtual void removeAll();
//	void removeEntity(TSimulationEntity*);
//	void addEntity(TSimulationEntity*);
//	bool hasEntity(TSimulationEntity* child);
//	void getEntitySet(std::set<TSimulationEntity*>& EntSet);
//	
//private:
//	std::set<TSimulationEntity*> m_SimEntitySet;
//};

}

#endif
